/**
 * @file YzhClassGrades.vue
 * @description 班级学生成绩页面 - 显示指定班级中所有学生的成绩
 * @created 2024-07-15
 */

<template>
  <div class="class-grades-container">
    <!-- 返回按钮 -->
    <div class="back-btn" @click="goBack">
      <span class="back-icon">←</span> 返回
    </div>
    
    <!-- 页面标题和信息 -->
    <div class="header-section">
      <h1 class="page-title">班级成绩详情</h1>
      <div v-if="!loading && classHeaderInfo" class="class-info">
        <div class="info-item">
          <span class="label">教师:</span>
          <span class="value">{{ classHeaderInfo.teacher_name }}</span>
        </div>
        <div class="info-item">
          <span class="label">课程:</span>
          <span class="value">{{ classHeaderInfo.course_name }}</span>
        </div>
        <div class="info-item">
          <span class="label">班级:</span>
          <span class="value">{{ classHeaderInfo.class_name }}</span>
        </div>
        <div class="info-item">
          <span class="label">学期:</span>
          <span class="value">{{ classHeaderInfo.semester }} {{ classHeaderInfo.year }}</span>
        </div>
      </div>
    </div>

    <!-- 加载状态 -->
    <div v-if="loading" class="loading-container">
      <div class="loading-spinner"></div>
      <div class="loading-text">加载成绩数据中...</div>
    </div>

    <!-- 统计信息 -->
    <div v-else-if="analysisData && students.length >= 0" class="stats-section">
          <div class="stat-card">
        <div class="stat-value">{{ analysisData.total_students !== null ? analysisData.total_students : 0 }}</div>
        <div class="stat-label">总人数</div>
          </div>
          <div class="stat-card">
        <div class="stat-value">{{ analysisData.average_score !== null ? analysisData.average_score.toFixed(1) : 'N/A' }}</div>
            <div class="stat-label">平均分</div>
          </div>
          <div class="stat-card">
        <div class="stat-value">{{ analysisData.pass_rate !== null ? analysisData.pass_rate.toFixed(1) : 'N/A' }}%</div>
        <div class="stat-label">通过率</div>
          </div>
          <div class="stat-card">
        <div class="stat-value">{{ analysisData.excellent_rate !== null ? analysisData.excellent_rate.toFixed(1) : 'N/A' }}%</div>
            <div class="stat-label">优秀率</div>
        </div>
      </div>
     <div v-else class="empty-data">暂无统计数据</div>

    <!-- 成绩分布图表 -->
    <div v-if="!loading && analysisData && analysisData.score_distribution && analysisData.total_students > 0" class="chart-container">
      <h2 class="section-title">成绩分布</h2>
      <div class="chart-placeholder">
        <div class="score-distribution">
          <div v-for="(count, range) in analysisData.score_distribution" :key="range" 
               class="score-bar" 
               :style="{ height: `${(count / (analysisData.total_students || 1)) * 150}px` }">
            <div class="score-value">{{ count }}</div>
            <div class="score-range">{{ range.replace('0-59', '<60') }}</div>
          </div>
        </div>
      </div>
    </div>
    <div v-else-if="!loading && students.length > 0" class="empty-data">暂无成绩分布数据 (可能所有学生均未评分)</div>


    <!-- 学生成绩表格 -->
    <div class="grades-table-section">
      <h2 class="section-title">学生成绩明细</h2>
      
      <div v-if="!loading && students.length === 0" class="empty-data">
        班级内暂无学生或无成绩数据
      </div>

      <div v-else-if="!loading" class="content-wrapper">
        <div class="search-filter">
        <input 
          type="text" 
          v-model="searchKeyword" 
          placeholder="搜索学生姓名或学号..." 
        />
        </div>
        
        <div class="table-container">
          <table class="grades-table">
            <thead>
              <tr>
                <th>学号</th>
                <th>姓名</th>
              <th>平时成绩</th>
              <th>考试成绩</th>
              <th>总评成绩</th>
              <th>状态</th>
                <th>操作</th>
              </tr>
            </thead>
            <tbody>
            <tr v-if="filteredStudents.length === 0">
                <td colspan="6" class="empty-data">没有匹配的学生</td>
            </tr>
            <tr v-for="student in filteredStudents" :key="student.student_id">
                <td>{{ student.student_code }}</td>
                <td>{{ student.name }}</td>
                <td>{{ getScoreDisplay(student.daily_score) }}</td>
                <td>{{ getScoreDisplay(student.exam_score) }}</td>
                <td :class="getScoreClass(student.score)">{{ getScoreDisplay(student.score) }}</td>
                <td :class="getStatusClass(student.score)">
                  {{ getScoreStatus(student.score) }}
                </td>
                <td>
                  <el-button type="primary" size="small" @click="handleEditScore(student)">
                    编辑成绩
                  </el-button>
                </td>
              </tr>
            </tbody>
          </table>
      </div>
    </div>
    </div>

    <!-- 编辑成绩对话框 -->
    <el-dialog 
      v-model="editDialogVisible" 
      title="编辑学生成绩" 
      width="40%" 
      @closed="handleDialogClose"
      destroy-on-close
    >
      <div v-if="editingStudentGrade">
        <p><strong>学生:</strong> {{ editingStudentGrade.name }} ({{ editingStudentGrade.student_code }})</p>
        <el-form 
          :model="editingStudentGrade" 
          :rules="formRules" 
          ref="editGradeFormRef" 
          label-width="100px"
          label-position="right"
        >
          <el-form-item label="平时成绩" prop="daily_score">
            <el-input-number v-model="editingStudentGrade.daily_score" :min="0" :max="100" controls-position="right" placeholder="可选" style="width: 100%;" />
          </el-form-item>
          <el-form-item label="考试成绩" prop="exam_score">
            <el-input-number v-model="editingStudentGrade.exam_score" :min="0" :max="100" controls-position="right" placeholder="可选" style="width: 100%;" />
          </el-form-item>
          <el-form-item label="总评成绩" prop="score">
            <el-input-number v-model="editingStudentGrade.score" :min="0" :max="100" controls-position="right" placeholder="必填" style="width: 100%;" />
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="editDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitEditGrade">保存</el-button>
        </span>
      </template>
    </el-dialog>

  </div>
</template>

<script setup>
/**
 * 班级学生成绩页面组件
 * @description 显示特定班级的学生成绩和统计信息
 */
import { ref, computed, onMounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { getClassStudentScores } from '@/api/admin/yzhTeacher';
import { ElMessage } from 'element-plus';

const router = useRouter();
const route = useRoute();
const teacherId = ref(route.params.teacherId);
const courseId = ref(route.params.courseId);
const classId = ref(route.params.classId);

// 数据状态
const loading = ref(true);
const classHeaderInfo = ref({ 
  class_name: '', 
  course_name: '',
  teacher_name: '',
  semester: '', 
  year: '' 
});
const students = ref([]);
const analysisData = ref(null); // 存储后端返回的分析数据
const searchKeyword = ref('');

// 定义静态图表数据
const staticChartData = {
  score_distribution: {
    '0-59': 5,
    '60-69': 12,
    '70-79': 15,
    '80-89': 8,
    '90-100': 3
  },
  pass_rate: 80.5, // 示例通过率
  excellent_rate: 15.2 // 示例优秀率
};

// 编辑成绩对话框相关
const editDialogVisible = ref(false);
const editingStudentGrade = ref(null); // 用于存储当前编辑的学生成绩信息
const editGradeFormRef = ref(null); // 表单引用

const formRules = {
  daily_score: [
    { validator: validateScore, trigger: 'blur' }
  ],
  exam_score: [
    { validator: validateScore, trigger: 'blur' }
  ],
  score: [
    { required: true, message: '总评成绩不能为空', trigger: 'blur' },
    { validator: validateScore, trigger: 'blur' }
  ]
};

// 自定义校验规则：0-100之间的数字
function validateScore(rule, value, callback) {
  if (value === null || value === '' || value === undefined) {
    // 允许为空，除非字段本身是required
    return callback(); 
  }
  const numValue = Number(value);
  if (isNaN(numValue)) {
    return callback(new Error('请输入数字'));
  }
  if (numValue < 0 || numValue > 100) {
    return callback(new Error('成绩必须在0到100之间'));
  }
  callback();
}

// 筛选后的学生列表
const filteredStudents = computed(() => {
  if (!searchKeyword.value) {
    return students.value;
  }
  
  const keyword = searchKeyword.value.toLowerCase();
  return students.value.filter(student => 
    (student.name && student.name.toLowerCase().includes(keyword)) || // 使用 student.name
    (student.student_code && student.student_code.toLowerCase().includes(keyword))
  );
});

// 获取成绩数据
const fetchGradeData = async () => {
  loading.value = true;
  try {
    const res = await getClassStudentScores(teacherId.value, courseId.value, classId.value);
    console.log('API响应 (班级成绩):', res);

    if (res && res.status === 'success' && res.data) {
      classHeaderInfo.value = {
        class_name: res.data.class_name || res.data.classInfo?.class_name || 'N/A',
        course_name: res.data.course_name || res.data.classInfo?.course_name || 'N/A',
        teacher_name: res.data.teacher_name || res.data.classInfo?.teacher_name || 'N/A',
        semester: res.data.semester || res.data.classInfo?.semester || '',
        year: res.data.year || res.data.classInfo?.year || ''
      };
      
      students.value = res.data.students || [];
      // 尝试从后端获取分析数据，如果失败或不存在，则 analysisData 保持 null
      analysisData.value = res.data.analysis || null; 

      console.log('处理后 学生列表:', students.value);
      console.log('处理后 统计分析 (可能为null):', analysisData.value);
      console.log('处理后 班级头信息:', classHeaderInfo.value);

    } else {
      students.value = [];
      analysisData.value = null; // 确保在API失败时 analysisData 为 null
      ElMessage.error(res.message || '获取成绩数据失败');
      console.error('获取成绩数据失败或响应格式不正确:', res);
       // 页眉也给默认值，避免N/A太突兀
      classHeaderInfo.value = {
        class_name: '班级信息获取失败',
        course_name: '课程信息获取失败',
        teacher_name: '教师信息获取失败',
        semester: '',
        year: ''
      };
    }
  } catch (error) {
    students.value = [];
    analysisData.value = null; // 确保在捕获到错误时 analysisData 为 null
    console.error('请求成绩数据API时发生错误:', error);
    ElMessage.error('请求成绩数据API时发生网络错误或服务器错误');
     classHeaderInfo.value = {
        class_name: '班级信息加载出错',
        course_name: '课程信息加载出错',
        teacher_name: '教师信息加载出错',
        semester: '',
        year: ''
      };
  } finally {
    loading.value = false;
    // 无论API成功与否，都尝试初始化/更新图表
    // initCharts 会优先使用 analysisData.value，如果为null，则使用 staticChartData
    nextTick(() => {
        initCharts();
    });
      }
};
  
// 辅助函数，用于在模板中安全地访问可能为null的score
const getScoreDisplay = (score) => {
  return score !== null && score !== undefined ? score : '未评分';
};

// 获取成绩对应的CSS类
const getScoreClass = (score) => {
  if (score === null || score === undefined || score === '未评分') return 'score-unrated';
  if (score < 60) return 'score-fail';
  if (score >= 90) return 'score-excellent';
  if (score >= 60) return 'score-pass';
  return 'score-unrated';
};

// 获取成绩状态文本
const getScoreStatus = (score) => {
  if (score === null || score === undefined || score === '未评分') return '未评分';
  if (score < 60) return '不及格';
  return '及格';
};

// 获取状态CSS类
const getStatusClass = (score) => {
  if (score === null || score === undefined) return '';
  if (score >= 90) return 'status-excellent';
  if (score >= 80) return 'status-good';
  if (score >= 70) return 'status-medium';
  if (score >= 60) return 'status-pass';
  return 'status-fail';
};

// 打开编辑成绩对话框
const handleEditScore = (student) => {
  console.log("Editing score for student:", student);
  editingStudentGrade.value = { 
    ...student, // 复制学生所有信息
    // 确保成绩字段是数字或null，以便表单正确处理
    daily_score: student.daily_score !== '未评分' && student.daily_score !== null && student.daily_score !== undefined ? Number(student.daily_score) : null,
    exam_score: student.exam_score !== '未评分' && student.exam_score !== null && student.exam_score !== undefined ? Number(student.exam_score) : null,
    score: student.score !== '未评分' && student.score !== null && student.score !== undefined ? Number(student.score) : null,
    // 需要 student_id 和 grade_id (如果存在) 或 teaching_assignment_id 用于API调用
    student_id: student.student_id,
    grade_id: student.grade_id, // grade_id 可能为 null 如果学生还没有成绩记录
    teaching_assignment_id: analysisData.value?.teaching_assignment_id || null // 从分析数据中获取教学安排ID
  };
  editDialogVisible.value = true;
};

// 提交编辑后的成绩
const submitEditGrade = async () => {
  if (!editGradeFormRef.value) return;
  await editGradeFormRef.value.validate(async (valid) => {
    if (valid) {
      try {
        console.log("Submitting grade:", editingStudentGrade.value);
        // TODO: 调用API更新成绩 - placeholder for now
        // const res = await updateStudentGradeApi(editingStudentGrade.value);
        // if (res.status === 'success') {
        //   ElMessage.success('成绩更新成功');
        //   editDialogVisible.value = false;
        //   fetchGradeData(); // 刷新列表
        // } else {
        //   ElMessage.error(res.message || '成绩更新失败');
        // }
        ElMessage.info('API调用更新成绩的功能待实现');
        // 模拟成功
        setTimeout(() => {
            editDialogVisible.value = false;
            // 可以在这里模拟更新列表中的数据，或者最好是重新获取
            const index = students.value.findIndex(s => s.student_id === editingStudentGrade.value.student_id);
            if (index !== -1) {
                students.value[index].score = editingStudentGrade.value.score;
                students.value[index].daily_score = editingStudentGrade.value.daily_score;
                students.value[index].exam_score = editingStudentGrade.value.exam_score;
            }
        }, 500);

      } catch (error) {
        console.error("更新成绩API调用失败:", error);
        ElMessage.error('更新成绩失败，请重试');
      }
    } else {
      console.log('表单验证失败');
      return false;
    }
  });
};

// 关闭对话框前清空
const handleDialogClose = () => {
  if (editGradeFormRef.value) {
    editGradeFormRef.value.resetFields();
  }
  editingStudentGrade.value = null;
};

onMounted(() => {
  fetchGradeData();
  // initCharts is now called in fetchGradeData's finally block
});

// 返回上一页
const goBack = () => {
  if (route.meta && route.meta.from) {
      router.push(route.meta.from);
  } else {
      router.back();
  }
};

// 图表初始化逻辑
const scoreDistributionChart = ref(null);
const gradeDistributionChart = ref(null);

const initCharts = () => {
  // 优先使用从API获取的 analysisData，如果为 null，则使用 staticChartData
  const currentAnalysis = analysisData.value;
  const chartDataSource = currentAnalysis || staticChartData;

  console.log("Initializing charts with data source:", chartDataSource);

  // 初始化成绩分布柱状图
  if (chartDataSource.score_distribution) {
    if (scoreDistributionChart.value) {
      const chartInstance = echarts.getInstanceByDom(scoreDistributionChart.value);
      if (chartInstance) {
        chartInstance.dispose(); // 销毁旧实例
      }
      const newScoreChartInstance = echarts.init(scoreDistributionChart.value);
      const scoreDist = chartDataSource.score_distribution;
      newScoreChartInstance.setOption({
        title: { text: `成绩分数段人数分布 ${currentAnalysis ? '(动态数据)' : '(静态演示数据)'}`, left: 'center' },
        tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
        xAxis: {
          type: 'category',
          data: ['0-59', '60-69', '70-79', '80-89', '90-100'],
          axisLabel: { interval: 0, rotate: 30 }
        },
        yAxis: { type: 'value', name: '人数' },
        series: [{
          name: '人数',
          type: 'bar',
          data: [
            scoreDist['0-59'] || 0,
            scoreDist['60-69'] || 0,
            scoreDist['70-79'] || 0,
            scoreDist['80-89'] || 0,
            scoreDist['90-100'] || 0
          ],
          barWidth: '60%',
          itemStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                  { offset: 0, color: '#83bff6' },
                  { offset: 0.5, color: '#188df0' },
                  { offset: 1, color: '#188df0' }
              ])
          },
        }]
      });
    } else {
      console.warn("柱状图的DOM元素 'scoreDistributionChart' 未找到。");
    }
  } else {
    console.warn("成绩分数段数据 (score_distribution) 缺失，无法渲染柱状图。");
  }

  // 初始化通过率/优秀率饼图
  if (chartDataSource.pass_rate !== undefined && chartDataSource.excellent_rate !== undefined) {
      if (gradeDistributionChart.value) { 
        const pieChartInstance = echarts.getInstanceByDom(gradeDistributionChart.value);
        if (pieChartInstance) {
            pieChartInstance.dispose();
        }
        const newPieChartInstance = echarts.init(gradeDistributionChart.value);
        newPieChartInstance.setOption({
            title: { text: `通过率与优秀率 ${currentAnalysis ? '(动态数据)' : '(静态演示数据)'}`, left: 'center' },
            tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c}% ({d}%)' },
            legend: { top: 'bottom' },
            series: [{
                name: '成绩评定',
                type: 'pie',
                radius: ['40%', '70%'],
                avoidLabelOverlap: false,
                label: { show: true, position: 'outside', formatter: '{b}: {c}% ({d}%)' },
                emphasis: { label: { show: true, fontSize: '16', fontWeight: 'bold' } },
                data: [
                    { value: chartDataSource.pass_rate, name: '通过率' },
                    { value: chartDataSource.excellent_rate, name: '优秀率' },
                    { value: parseFloat((100 - chartDataSource.pass_rate).toFixed(1)), name: '未通过率' }
                ]
            }]
        });
      } else {
          console.warn("饼图的DOM元素 'gradeDistributionChart' 未找到。");
      }
  } else {
      console.warn("通过率或优秀率数据缺失，无法渲染饼图。");
  }
};

const clearCharts = () => {
  if (scoreDistributionChart.value) {
    const chartInstance = echarts.getInstanceByDom(scoreDistributionChart.value);
    if (chartInstance) chartInstance.dispose();
  }
  if (gradeDistributionChart.value) {
    const chartInstance = echarts.getInstanceByDom(gradeDistributionChart.value);
    if (chartInstance) chartInstance.dispose();
  }
};
</script>

<style scoped>
.class-grades-container {
  padding: 30px;
  max-width: 1200px;
  margin: 0 auto;
}

.back-btn {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  margin-bottom: 20px;
  padding: 8px 16px;
  background-color: #f0f2f5;
  border-radius: 4px;
  transition: all 0.3s;
}

.back-btn:hover {
  background-color: #e6f7ff;
  color: #1890ff;
}

.back-icon {
  margin-right: 8px;
  font-size: 16px;
  font-weight: bold;
}

.header-section {
  margin-bottom: 30px;
}

.page-title {
  font-size: 24px;
  margin: 0 0 15px 0;
  color: #1a1a1a;
}

.class-info {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  background-color: white;
  padding: 15px;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}

.info-item {
  display: flex;
  align-items: center;
}

.info-item .label {
  color: #666;
  margin-right: 8px;
  font-weight: 500;
}

.info-item .value {
  color: #1a1a1a;
}

.loading-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 0;
}

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #f3f3f3;
  border-top: 4px solid #3498db;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 15px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.loading-text {
  color: #666;
  font-size: 14px;
}

.stats-section {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 20px;
  margin-bottom: 30px;
}

.stat-card {
  background-color: white;
  border-radius: 8px;
  padding: 20px;
  text-align: center;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
  transition: all 0.3s;
}

.stat-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
}

.stat-value {
  font-size: 32px;
  font-weight: bold;
  color: #1890ff;
  margin-bottom: 5px;
}

.stat-label {
  font-size: 14px;
  color: #666;
}

.chart-container {
  background-color: white;
  border-radius: 8px;
  padding: 20px;
  margin-bottom: 30px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}

.section-title {
  font-size: 18px;
  margin: 0 0 15px 0;
  padding-bottom: 10px;
  border-bottom: 1px solid #f0f0f0;
  color: #1a1a1a;
}

.chart-placeholder {
  height: 200px;
  display: flex;
  justify-content: center;
  align-items: flex-end;
}

.score-distribution {
  display: flex;
  justify-content: space-around;
  align-items: flex-end;
  width: 80%;
  height: 180px;
}

.score-bar {
  width: 18%;
  background-color: #e6f7ff;
  border-radius: 4px 4px 0 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  transition: all 0.3s;
  min-height: 20px;
}

.score-bar:nth-child(1) { background-color: #f6ffed; }
.score-bar:nth-child(2) { background-color: #e6f7ff; }
.score-bar:nth-child(3) { background-color: #fff7e6; }
.score-bar:nth-child(4) { background-color: #fff2e8; }
.score-bar:nth-child(5) { background-color: #fff1f0; }

.score-value {
  margin-bottom: 10px;
  font-weight: bold;
  color: #1a1a1a;
}

.score-range {
  position: relative;
  top: 25px;
  color: #666;
  font-size: 12px;
}

.grades-table-section {
  background-color: white;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}

.empty-data {
  text-align: center;
  padding: 30px;
  color: #999;
  font-size: 14px;
  background-color: #fafafa;
  border-radius: 4px;
}

.search-filter {
  margin-bottom: 15px;
}

.search-filter input {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  font-size: 14px;
}

.search-filter input:focus {
  outline: none;
  border-color: #1890ff;
}

.table-container {
  overflow-x: auto;
}

.grades-table {
  width: 100%;
  border-collapse: collapse;
}

.grades-table th, .grades-table td {
  padding: 12px 15px;
  text-align: left;
  border-bottom: 1px solid #f0f0f0;
}

.grades-table th {
  background-color: #fafafa;
  font-weight: 500;
  color: #1a1a1a;
}

.grades-table tr:hover {
  background-color: #fafafa;
}

.score-excellent { color: #52c41a; font-weight: bold; }
.score-good { color: #1890ff; font-weight: bold; }
.score-medium { color: #faad14; font-weight: bold; }
.score-pass { color: #fa8c16; font-weight: bold; }
.score-fail { color: #f5222d; font-weight: bold; }

.status-excellent {
  background-color: #f6ffed;
  color: #52c41a;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 12px;
}

.status-good {
  background-color: #e6f7ff;
  color: #1890ff;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 12px;
}

.status-medium {
  background-color: #fff7e6;
  color: #faad14;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 12px;
}

.status-pass {
  background-color: #fff2e8;
  color: #fa8c16;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 12px;
}

.status-fail {
  background-color: #fff1f0;
  color: #f5222d;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 12px;
}
</style> 